package com.ctrip.framework.apollo.biz.service;

import com.ctrip.framework.apollo.biz.entity.Cluster;
import com.ctrip.framework.apollo.common.entity.App;
import com.ctrip.framework.apollo.core.ConfigConsts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

@Service
public class AdminService {
  private final static Logger logger = LoggerFactory.getLogger(AdminService.class);

  private final AppService appService;
  private final AppNamespaceService appNamespaceService;
  private final ClusterService clusterService;
  private final NamespaceService namespaceService;

  public AdminService(
      final AppService appService,
      final @Lazy AppNamespaceService appNamespaceService,
      final @Lazy ClusterService clusterService,
      final @Lazy NamespaceService namespaceService) {
    this.appService = appService;
    this.appNamespaceService = appNamespaceService;
    this.clusterService = clusterService;
    this.namespaceService = namespaceService;
  }

  /**
   * 第 15 至 18 行：调用 AppService#save(App) 方法，保存 App 对象到数据库中。
   * 第 20 行：调用 AppNamespaceService#createDefaultAppNamespace(appId, createBy) 方法，
   * 创建 App 的默认 Namespace (命名空间) "application" 。具体的代码实现，我们在 《Apollo 源码解析 —— Portal 创建 Namespace》 详细解析。
   * ========== 如下部分，是 Admin Service 独有 ==========
   * App 下有哪些 Cluster ，在 Portal 中是不进行保存，通过 Admin Service API 读取获得。
   * 【AppNamespace】第 22 行：调用 ClusterService#createDefaultCluster(appId, createBy) 方法，
   * 创建 App 的默认 Cluster "default" 。后续文章，详细分享。
   * 【Namespace】第 24 行：调用 NamespaceService#instanceOfAppNamespaces(appId, createBy) 方法，创建 Cluster 的默认命名空间。
   *
   * @param app
   * @return
   */
  @Transactional
  public App createNewApp(App app) {
    // 保存 App 对象到数据库
    String createBy = app.getDataChangeCreatedBy();
    App createdApp = appService.save(app);

    String appId = createdApp.getAppId();
    // 创建 App 的默认命名空间 "application"
    appNamespaceService.createDefaultAppNamespace(appId, createBy);
    // 创建 App 的默认集群 "default"
    clusterService.createDefaultCluster(appId, createBy);
    // 创建 Cluster 的默认命名空间
    namespaceService.instanceOfAppNamespaces(appId, ConfigConsts.CLUSTER_NAME_DEFAULT, createBy);

    return app;
  }

  @Transactional
  public void deleteApp(App app, String operator) {
    String appId = app.getAppId();

    logger.info("{} is deleting App:{}", operator, appId);

    List<Cluster> managedClusters = clusterService.findParentClusters(appId);

    // 1. delete clusters
    if (Objects.nonNull(managedClusters)) {
      for (Cluster cluster : managedClusters) {
        clusterService.delete(cluster.getId(), operator);
      }
    }

    // 2. delete appNamespace
    appNamespaceService.batchDelete(appId, operator);

    // 3. delete app
    appService.delete(app.getId(), operator);
  }
}
